package org.jeecg.modules.clue.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.StringUtil;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.clue.entity.ClueRecordTask;
import org.jeecg.modules.clue.entity.ClueTaskPushDayReport;
import org.jeecg.modules.clue.mapper.ClueTaskPushDayReportMapper;
import org.jeecg.modules.clue.service.IClueRecordTaskService;
import org.jeecg.modules.clue.service.IClueTaskPushDayReportService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Description: 线索任务推送日报表
 * @Author: jeecg-boot
 * @Date:   2025-01-15
 * @Version: V1.0
 */
@Slf4j
@Service
public class ClueTaskPushDayReportServiceImpl extends ServiceImpl<ClueTaskPushDayReportMapper, ClueTaskPushDayReport> implements IClueTaskPushDayReportService {

    @Resource
    ISysUserService sysUserService;
    @Resource
    IClueRecordTaskService clueRecordTaskService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void countByDate(String date) {
        Date currentDate = DateUtil.parse(date);
        //一天的开始
        Date beginOfDay = DateUtil.beginOfDay(currentDate);
        //一天的结束
        Date endOfDay = DateUtil.endOfDay(currentDate);
        // 获取所有正常用户
        List<SysUser> userList = sysUserService.list(new LambdaQueryWrapper<SysUser>().eq(SysUser::getStatus,1));
        // 获取每个用户 date 这天 的推送量
        List<ClueTaskPushDayReport> pushDayReportList = userList.stream().map(sysUser -> {
            long count = clueRecordTaskService.count(new LambdaQueryWrapper<ClueRecordTask>()
                    .eq(ClueRecordTask::getSource, sysUser.getUsername())
                    .between(ClueRecordTask::getCreateTime, beginOfDay, endOfDay)
            );


            ClueTaskPushDayReport dayReport = getOne(new LambdaQueryWrapper<ClueTaskPushDayReport>().eq(ClueTaskPushDayReport::getUsername, sysUser.getUsername())
                    .eq(ClueTaskPushDayReport::getPushDate, currentDate)
            );

            if (null == dayReport) {
                dayReport = new ClueTaskPushDayReport();
            }
            dayReport.setId(null);
            dayReport.setPushDate(currentDate);
            dayReport.setUsername(sysUser.getUsername());
            dayReport.setPushNum(BigDecimal.valueOf(count));
            return dayReport;
        }).collect(Collectors.toList());
        // 先删除，在新增
        remove(new LambdaQueryWrapper<ClueTaskPushDayReport>().in(ClueTaskPushDayReport::getUsername,userList.stream().map(SysUser::getUsername).collect(Collectors.toList())).eq(ClueTaskPushDayReport::getPushDate,currentDate));
        saveBatch(pushDayReportList);

    }

    @Override
    public List<JSONObject> summaryList(HttpServletRequest req) {

        Map<String, String[]> parameterMap = req.getParameterMap();
        String[] pushDateBegins = parameterMap.getOrDefault("pushDate_begin", new String[0]);
        String[] pushDateEnds = parameterMap.getOrDefault("pushDate_end",new String[0]);
        String[] usernames = parameterMap.getOrDefault("username", new String[0]);

       String pushDateBegin=  pushDateBegins.length > 0?pushDateBegins[0]:"";
       String pushDateEnd=  pushDateEnds.length > 0?pushDateEnds[0]:"";
       String username=  usernames.length > 0?usernames[0]:"";



        log.info("parameterMap {}",JSONObject.toJSONString(parameterMap));

        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String roleCode = sysUser.getRoleCode();
        List<String> roleCodes = Arrays.asList(Optional.ofNullable(roleCode).orElse("").split(","));
        // 当前角色不是 管理员
        if (!roleCodes.contains("plain_admin") &&  !roleCodes.contains("admin")) {
            String yesterdayDateStr = DateUtil.format(DateUtil.yesterday().toJdkDate(), "yyyy-MM-dd");

            List<ClueTaskPushDayReport> list = list(new LambdaQueryWrapper<ClueTaskPushDayReport>()
                    .eq(ClueTaskPushDayReport::getUsername, sysUser.getUsername())
                    .ge(StringUtils.isNotBlank(pushDateBegin), ClueTaskPushDayReport::getPushDate, pushDateBegin)
                    .le(StringUtils.isNotBlank(pushDateEnd), ClueTaskPushDayReport::getPushDate, pushDateEnd))

                    .parallelStream().map(new Function<ClueTaskPushDayReport, ClueTaskPushDayReport>() {
                        @Override
                        public ClueTaskPushDayReport apply(ClueTaskPushDayReport clueTaskPushDayReport) {
                            // 今天4点之前的建单量不显示
                            Date pushTime = clueTaskPushDayReport.getPushDate();
                            String createDateStr = DateUtil.format(pushTime, "yyyy-MM-dd");
                            if (yesterdayDateStr.equals(createDateStr)) {
                                if (DateUtil.hour(DateUtil.date(),true)  < 16) {
                                    clueTaskPushDayReport.setBuildNum(null);
                                }
                            }
                            return clueTaskPushDayReport;
                        }
                    }).collect(Collectors.toList());
                    ;



            BigDecimal pushNum = list.parallelStream().map(ClueTaskPushDayReport::getPushNum).reduce(BigDecimal.ZERO, (bigDecimal, bigDecimal2) -> bigDecimal.add(null == bigDecimal2 ? BigDecimal.ZERO : bigDecimal2));
            BigDecimal buildNum = list.parallelStream().map(ClueTaskPushDayReport::getBuildNum).reduce(BigDecimal.ZERO, (bigDecimal, bigDecimal2) -> bigDecimal.add(null == bigDecimal2 ? BigDecimal.ZERO : bigDecimal2));
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("_index", "合计");
            jsonObject.put("_row", "合计");
            jsonObject.put("key", UUID.randomUUID().toString());
            jsonObject.put("buildNum", buildNum);
            jsonObject.put("pushNum", pushNum);
            jsonObject.put("username_dictText", sysUser.getUsername());
            jsonObject.put("pushDate", "");
            if (StringUtils.isNotBlank(pushDateBegin) && StringUtils.isNotBlank(pushDateEnd)) {
                jsonObject.put("pushDate", String.format("%s至%s", pushDateBegin, pushDateEnd));

            }
            return Collections.singletonList(jsonObject);

        }else{
            List<String> sources = StringUtils.isBlank(username) ? sysUserService.list(new LambdaQueryWrapper<SysUser>().eq(SysUser::getStatus, 1)).parallelStream().map(SysUser::getUsername).collect(Collectors.toList()): Arrays.asList(username.split(","));
            if (sources.isEmpty()) {
                return Collections.emptyList();
            }
            List<JSONObject> collect = sources.parallelStream().map(source -> {

                List<ClueTaskPushDayReport> list = list(new LambdaQueryWrapper<ClueTaskPushDayReport>()
                        .eq(ClueTaskPushDayReport::getUsername, source)
                        .ge(StringUtils.isNotBlank(pushDateBegin), ClueTaskPushDayReport::getPushDate, pushDateBegin)
                        .le(StringUtils.isNotBlank(pushDateEnd), ClueTaskPushDayReport::getPushDate, pushDateEnd)
                );
                BigDecimal pushNum = list.parallelStream().map(ClueTaskPushDayReport::getPushNum).reduce(BigDecimal.ZERO, (bigDecimal, bigDecimal2) -> bigDecimal.add(null == bigDecimal2 ? BigDecimal.ZERO : bigDecimal2));
                BigDecimal buildNum = list.parallelStream().map(ClueTaskPushDayReport::getBuildNum).reduce(BigDecimal.ZERO, (bigDecimal, bigDecimal2) -> bigDecimal.add(null == bigDecimal2 ? BigDecimal.ZERO : bigDecimal2));
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("_index", "合计");
                jsonObject.put("_row", "合计");
                jsonObject.put("key", UUID.randomUUID().toString());
                jsonObject.put("buildNum", buildNum);
                jsonObject.put("pushNum", pushNum);
                jsonObject.put("username_dictText", source);
                jsonObject.put("pushDate", "");
                if (StringUtils.isNotBlank(pushDateBegin) && StringUtils.isNotBlank(pushDateEnd)) {
                    jsonObject.put("pushDate", String.format("%s至%s", pushDateBegin, pushDateEnd));

                }
                return jsonObject;
            }).collect(Collectors.toList());
            return collect;

        }



    }
}
